package org.fireflow2.designer.eclipse.modelwrapper;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.draw2d.geometry.Rectangle;

public abstract class AbsWrapper implements Wrapper{

	private PropertyChangeSupport listeners = new PropertyChangeSupport(this);

	private Wrapper parent = null;
	private List<Wrapper> children = new ArrayList<Wrapper>();

	Rectangle defaultRectangle = new Rectangle(0, 0, 20, 20);
	IProject project = null;
	
	public IProject getProject(){
		if (this.project==null){
			if (parent!=null){
				return parent.getProject();
			}
		}
		return project;
	}
	public void setProject(IProject project){
		this.project = project;
	}

	public void addPropertyChangeListener(PropertyChangeListener l) {
		PropertyChangeListener[] existsListeners = listeners.getPropertyChangeListeners();
		boolean found = false;
		if (existsListeners!=null){
			for (PropertyChangeListener existListner : existsListeners){
				if (existListner==l){
					found = true;
					break;
				}
			}
		}
		if (!found){
			listeners.addPropertyChangeListener(l);
		}
	}

	public final void firePropertyChange(String prop, Object old, Object newValue) {
		try {
			listeners.firePropertyChange(prop, old, newValue);
			if (parent != null) {
				((AbsWrapper)parent).firePropertyChange(DIRTY, null, null);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public final void fireStructureChange(String prop, Object child) {
		try {
			
			listeners.firePropertyChange(prop, null, child);
			if (parent != null) {
				((AbsWrapper)parent).firePropertyChange(DIRTY, null, null);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public final void fireSimulationPropertyChange(String prop) {
		try {
			listeners.firePropertyChange(prop, null, null);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	public void removePropertyChangeListener(PropertyChangeListener l) {
		listeners.removePropertyChangeListener(l);
	}



	public Wrapper getParent() {
		return parent;
	}

	public void setParent(AbsWrapper parent) {
		this.parent = parent;
	}

	public boolean equals(Object obj) {
		if (obj == null || !(obj instanceof AbsWrapper)) {
			return false;
		}
		Wrapper wrapper = ((Wrapper) obj);
		if (wrapper.getSn().equals(this.getSn())){
			return true;
		}
		return false;
	}


	public List<Wrapper> getChildren(){
		return children;
	}
	
	public void orphanChild(Wrapper child){
		child.setParent(null);
		this.children.remove(child);
		this.fireStructureChange(child.getElementType(), child);
	}
	
	public void acceptChild(Wrapper child){
		this.addChild(child,-1);
	}
	
	public int deleteChild(Wrapper wrapper){
		int i = children.indexOf(wrapper);
		children.remove(wrapper);
		
		this.fireStructureChange(wrapper.getElementType(), wrapper);
		return i;
	}
	
	public void addChild(Wrapper child,int index){
		if (index<0 || index>this.children.size()){ 
			this.children.add(child);//追加在末尾
		}else{
			this.children.add(index, child);
		}
		
		this.fireStructureChange(child.getElementType(), child);
	}
	
	public void addChild(Wrapper wrapper){

		this.addChild(wrapper,-1);

		
	}	
	
	public String getElementType(){
		return "";
	}
	
	
	public static Wrapper findRootWrapper(Wrapper wrapper){
		Wrapper w = wrapper.getParent();
		if (w==null) return wrapper;
		else {
			return findRootWrapper(w);
		}
	}
}
